from typing import Tuple
from math import floor
from tkinter import *
from enum import Enum
from tkinter import messagebox
import time
import winsound
from lib.SJsonDB.SJsonDB import SJsonDB


class AppState(Enum):
    '应用状态'
    NO_WORK = 1
    '未工作状态'
    WORK = 2
    '工作状态'
    PAUSE_WORK = 3
    '暂停工作状态'
    SUER_WORK_END_STATE = 4
    '确定工作时间结束状态'
    REST = 5
    '休息状态'


class Application():
    KEY_WORK_TIME = 'workTime'
    KEY_REST_TIME = 'restTime'
    KEY_WORK_IMMEDIATELY_AFTER_STARTUP = 'workImmediatelyAfterStartup'
    KEY_RECORD_POSITION = 'recordPosition'
    KEY_POSITION = 'position'

    winWidth = 100
    '窗口宽'
    winHeight = 50
    '窗口高'
    workTime = 45*60
    '工作时间'
    restTime = 15*60
    '休息时间'
    workImmediatelyAfterStartup = False
    '启动后立即进行工作'
    recordPosition: bool = False
    '记录图标位置'

    def __init__(self):
        self.db = SJsonDB('config.json')
        '数据'

        if self.db.count() == 0:
            self.db.set(self.KEY_WORK_TIME, self.workTime)
            self.db.set(self.KEY_REST_TIME, self.restTime)
            self.db.set(self.KEY_WORK_IMMEDIATELY_AFTER_STARTUP,
                        self.workImmediatelyAfterStartup)
            self.db.set(self.KEY_RECORD_POSITION, self.recordPosition)
            self.db.save()
        else:
            if self.db.has(self.KEY_WORK_TIME):
                Application.workTime = self.db.get(self.KEY_WORK_TIME)
            if self.db.has(self.KEY_REST_TIME):
                Application.restTime = self.db.get(self.KEY_REST_TIME)
            if self.db.has(self.KEY_WORK_IMMEDIATELY_AFTER_STARTUP):
                Application.workImmediatelyAfterStartup = self.db.get(
                    self.KEY_WORK_IMMEDIATELY_AFTER_STARTUP)
            if self.db.has(self.KEY_RECORD_POSITION):
                Application.recordPosition = self.db.get(
                    self.KEY_RECORD_POSITION)
            Application.position = self.getViewPosition()

        self.appState = AppState.NO_WORK
        self.times = []

        self.createView()

    def createView(self):
        '创建界面'
        # 主窗口
        pos = self.getViewPosition()

        self.root = Tk()
        self.root.title('RegularRestReminder')
        self.root.geometry('%dx%d+%d+%d' %
                           (self.winWidth, self.winHeight, pos[0], pos[1]))
        self.root.resizable(False, False)
        self.root.overrideredirect(True)

        self.label = Label(self.root,
                           fg='black')
        self.label.pack(expand='yes', fill='both')

        # 拖拽
        self.root.bind('<ButtonPress-2>', self.onMouse_buttonPress_2)
        self.root.bind('<B2-Motion>', self.onMouse_b2_motion)

        # 右键菜单
        self.root.bind('<ButtonRelease-3>', self.onMouse_buttonRelease_3)

        # 右键点击
        self.root.bind('<ButtonRelease-1>', self.onMouse_buttonRelease_1)

        self.refreshFace()
        self.root.after(1000, self.onUpdate)

        if self.workImmediatelyAfterStartup:
            self.onMouse_buttonRelease_1(None)

        self.root.mainloop()

    def onMouse_buttonPress_2(self, event):
        '按下中键'
        self.lastDragPos = (event.x_root, event.y_root)

    def onMouse_b2_motion(self, event):
        '拖拽中键'
        dis = (event.x_root -
               self.lastDragPos[0], event.y_root - self.lastDragPos[1])
        self.lastDragPos = (event.x_root, event.y_root)
        newPos = (self.root.winfo_x() +
                  dis[0], self.root.winfo_y() + dis[1])
        self.root.geometry(
            '%dx%d+%d+%d' % (self.winWidth, self.winHeight, newPos[0], newPos[1]))

        if self.recordPosition:
            self.recordViewPosition(newPos)

    def onMouse_buttonRelease_3(self, event):
        '释放右键'
        self.exit()

    def onMouse_buttonRelease_1(self, event):
        '释放左键'
        if self.appState == AppState.NO_WORK:
            self.appState = AppState.WORK
            self.resetDuration()
        elif self.appState == AppState.WORK:
            self.appState = AppState.PAUSE_WORK
            self.times.append(self.getDuration())
        elif self.appState == AppState.PAUSE_WORK:
            self.appState = AppState.WORK
            self.lastTime = time.time().__int__()
        elif self.appState == AppState.SUER_WORK_END_STATE:
            self.appState = AppState.REST
            self.resetDuration()
        elif self.appState == AppState.REST:
            return
        else:
            self.warning_unknownState('onMouse_buttonRelease_1()')

        self.refreshFace()

    def exit(self):
        if self.recordPosition:
            self.db.save()
        self.root.destroy()

    def refreshFace(self):
        self.root.attributes('-topmost', False)

        if self.appState == AppState.NO_WORK:
            self.label.config(bg='#f0f8ff',
                              text='开始工作')
        elif self.appState == AppState.WORK:
            self.label.config(bg='#088da5')
            self.onUpdate(False)
        elif self.appState == AppState.PAUSE_WORK:
            self.label.config(bg='#f0f8ff',
                              text='继续工作')
        elif self.appState == AppState.SUER_WORK_END_STATE:
            self.label.config(bg='#FF6666',
                              text='确认结束工作')
            self.root.attributes('-topmost', True)
        elif self.appState == AppState.REST:
            self.label.config(bg='#008000')
            self.onUpdate(False)
        else:
            self.warning_unknownState('refreshFace()')

    def warning_unknownState(self, info):
        str = '未知状态 %s' % info
        print(str)
        messagebox.showwarning('警告', str)

    def onUpdate(self, after=True):
        if self.appState == AppState.WORK:
            delta = self.workTime - self.getTotalDuration()

            if delta > 0:
                self.label.config(text=self.formatTime(delta))
            else:
                self.appState = AppState.SUER_WORK_END_STATE
                self.refreshFace()
                self.playTipSound()
        elif self.appState == AppState.REST:
            delta = self.restTime - self.getDuration()

            if delta > 0:
                self.label.config(text=self.formatTime(delta))
            else:
                self.appState = AppState.NO_WORK
                self.refreshFace()
                self.playTipSound()
        if after:
            self.root.after(1000, self.onUpdate)

    def formatTime(self, totalSecond):
        if(totalSecond >= 86399):  # 23:59:59  23*60*60+59*60+59=86399
            return '23:59:59'

        h = floor(totalSecond / 3600)
        totalSecond -= h * 3600
        m = floor(totalSecond / 60)
        totalSecond -= m * 60
        return '%02d:%02d:%02d' % (h, m, totalSecond)

    def getDuration(self):
        '获得距离上个时间记录点过去了多少秒'
        return time.time().__int__() - self.lastTime

    def getTotalDuration(self):
        '获得记录的总时间'
        t = time.time().__int__() - self.lastTime
        for i in range(len(self.times)):
            t += self.times[i]
        return t

    def resetDuration(self):
        '重置记录的时间'
        self.lastTime = time.time().__int__()
        self.times.clear()

    def playTipSound(self):
        '播放提示声音'
        winsound.PlaySound(
            'SystemAsterisk', winsound.SND_ALIAS | winsound.SND_ASYNC)

    def getViewPosition(self) -> Tuple[int, int]:
        '获得图标位置'
        if self.db.has(self.KEY_POSITION):
            return self.db.get(self.KEY_POSITION)
        else:
            return (0, 0)

    def recordViewPosition(self, pos: Tuple[int, int]):
        '记录图标位置'
        self.db.set(self.KEY_POSITION, pos)


app = Application()
